package chapter14;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map;

/**
 * @author : DuJiabao
 * @Date : 2021/2/25 11:04
 * @Project : thinking_in_java
 * @File : null.java
 * @Desc :
 */
public class TypeCounter extends HashMap<Class<?>, Integer> {
  private Class<?> baseType;  // 基类

  public TypeCounter(Class<?> baseType) {
    this.baseType = baseType;
  }

  /**
   * 输入一个对象，对该的类及其超类进行计数
   *
   * @param obj
   */
  public void count(Object obj) {
    Class<?> type = obj.getClass();
    if (!baseType.isAssignableFrom(type)) {  // 判断是否为基类的继承类
      throw new RuntimeException(obj + " incorrect type: " + type + ", should be type or subtype of");
    }
    countClass(type);
  }

  /**
   * 添加某个Class的计数
   *
   * @param type
   */
  private void countClass(Class<?> type) {
    Integer quantity = get(type);  // 获取当前的个数
    put(type, quantity == null ? 1 : quantity + 1);
    Class<?> superclass = type.getSuperclass();
    if (superclass != null && baseType.isAssignableFrom(type)) { // 递归超类
      countClass(superclass);
    }
  }

  @Override
  public String toString() {
    StringBuilder result = new StringBuilder("{");
    for (Map.Entry<Class<?>, Integer> entry : entrySet()) {
      result.append(entry.getKey()).append("=").append(entry.getValue()).append(", ");  // 它返回自己，使得可以连续append
    }
    result.delete(result.length() - 2, result.length());  // 左闭右开
    result.append("}");
    return result.toString();
  }

  public static void main(String[] args) {
    TypeCounter counter = new TypeCounter(Object.class);
    counter.count(new ArrayList());
    counter.count(new LinkedList());
    System.out.println(counter);
  }
}
